import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { DeepPartial, FindOptionsWhere, Repository } from 'typeorm';
import { Order, orderStatustype } from './models/order.entity';
import { Result } from '../../dto/result.type';

@Injectable()
export class OrderService {
  constructor(
    @InjectRepository(Order)
    private readonly orderRepository: Repository<Order>,
  ) {}

  async create(entity: DeepPartial<Order>): Promise<boolean> {
    const res = await this.orderRepository.save(
      this.orderRepository.create(entity),
    );
    return !!res;
  }

  async findByCode(orderCode: string): Promise<Order> {
    return this.orderRepository.findOne({
      where: {
        orderCode,
      },
    });
  }

  async findByProduct(productId: string, userId: string): Promise<Order[]> {
    return this.orderRepository.findBy({
      productId,
      userId,
      status: orderStatustype.PAYMENT_OVER,
    });
  }

  async cancelOrder(orderCode: string): Promise<Result> {
    const existEntity = await this.findByCode(orderCode);
    if (!existEntity) {
      return {
        message: '不存在该订单',
        code: false,
      };
    }
    Object.assign(existEntity, { status: orderStatustype.REFUND });
    const res = await this.orderRepository.save(existEntity);
    return res
      ? { message: '更新成功', code: true }
      : { message: '更新失败', code: false };
  }

  async findOrders({
    start,
    length,
    where,
  }: {
    start: number;
    length: number;
    where: FindOptionsWhere<Order>;
  }): Promise<[Order[], number]> {
    return this.orderRepository.findAndCount({
      take: length,
      skip: start,
      where,
      order: {
        id: 'DESC',
      },
    });
  }

  async delete(id: string, userId: string): Promise<boolean> {
    const res1 = await this.orderRepository.update(id, {
      deletedBy: userId,
    });
    if (res1) {
      const res = await this.orderRepository.softDelete(id);
      if (res.affected > 0) {
        return true;
      }
    }
    return false;
  }
}
